local HerbInventory     = LibStub( "AceAddon-3.0" ):NewAddon( "Broker_HerbInventory", "AceTimer-3.0" )
local L               = LibStub:GetLibrary( "AceLocale-3.0" ):GetLocale( "Broker_HerbInventory" )
local AC	          = LibStub( "AceConfig-3.0" )
local ACD 			  = LibStub( "AceConfigDialog-3.0" )
local ACR	    	  = LibStub( "AceConfigRegistry-3.0" )
local ADO			  = LibStub( "AceDBOptions-3.0")
local LTT             = LibStub:GetLibrary( "LibQTip-1.0" )
local Crayon          = LibStub( "LibCrayon-3.0" )
local LDB	      = LibStub( "LibDataBroker-1.1" )
local MODNAME         = "HerbInventory"
local addon   	      = HerbInventory
local addonversion    = GetAddOnMetadata("Broker_HerbInventory", "X-Version")  
local addonauthor     = GetAddOnMetadata("Broker_HerbInventory", "X-Author") 
local builddate       = GetAddOnMetadata("Broker_HerbInventory", "X-Build")
local iconpath  	  = "Interface\\AddOns\\Broker_HerbInventory\\images\\"
local tinsert		  = table.insert
local db, chardb, charsdb, linecount, colnum, x, tooltip, scale, updatetime
local modularOptions, justification, names, charsToPurge, charsList  = {}, {}, {}, {}, {}
local GetItemCount    = GetItemCount
local playerName      = UnitName("player")
local charToPurge     = "None"
local LK_COLOR    		  = "|cff0066ff"
local BC_COLOR   		  = "|cff00ff00"
local CLASSIC_COLOR  		  = "|cff00ffff"

local DEBUG = false

local classColors = {}
for class, color in pairs(CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS) do
	classColors[class] = string.format( "%2x%2x%2x", color.r * 255, color.g * 255, color.b * 255 )
end

if CUSTOM_CLASS_COLORS then
	CUSTOM_CLASS_COLORS:RegisterCallback(
	   function()
	      for class, color in pairs(CUSTOM_CLASS_COLORS) do
		 classColors[class] = string.format( "%2x%2x%2x", color.r * 255, color.g * 255, color.b * 255 )
	      end
	   end)
end

local items = {
-- Id's for Classic herbs
	["classic"]               = {13468,
				     19726,
				     13467,
				     13466,
				     13465,
				     13463,
				     13464,
				     8846,
				     8839,
				     8845,
				     8838,
				     8836,
				     8831,
				     4625,
				     8153,
				     3819,
				     3358,
				     3821,
				     3818,
				     3357,
				     3356,
				     3355,
				     3369,
				     2453,
				     3820,
				     2452,
				     2450,
				     2449,
				     785,
				     765,
				     2447,
				     22710},
	
-- Strings for classic herbs
	["classicstrings"]        = {"Black Lotus", 
				     "Bloodvine",
				     "Icecap",
				     "Plaguebloom",
				     "Mountain Silversage",
				     "Dreamfoil",
				     "Golden Sansam",
				     "Gromsblood",
				     "Blindweed",
				     "Ghost Mushroom",
				     "Sungrass",
				     "Arthas\' Tears",
				     "Purple Lotus",
				     "Firebloom",
				     "Wildvine ",
				     "Wintersbite",
				     "Khadgar\'s Whisker",
				     "Goldthorn",
				     "Fadeleaf",
				     "Liferoot",
				     "Kingsblood",
				     "Wild Steelbloom",
				     "Grave Moss",
				     "Bruiseweed",
				     "Stranglekelp",
				     "Swiftthistle",
				     "Briarthorn",
				     "Earthroot",
				     "Mageroyal",
				     "Silverleaf",
				     "Peacebloom",
				     "Bloodthistle"}, 

-- IDs for BC herbs
	["burningcrusade"] 		  = {22792,
					     22793,
					     22794,
					     22791,
					     22797,
					     22790,
					     22788,
					     22787,
					     32468,
					     22785,
					     22786,
					     22789},
-- Strings for BC herbs	
	["burningcrusadestrings"] = {"Nightmare Vine",
				     "Mana Thistle", 
				     "Fel Lotus", 	
				     "Netherbloom", 
				     "Nightmare Seed", 	
				     "Ancient Lichen", 
				     "Flame Cap", 	
				     "Ragveil",
				     "Netherdust Pollen",
				     "Felweed",
				     "Dreaming Glory",
				     "Terocone"},

-- List of item ID's for Lich King herbs
	["lichking"]			  = {36908,
					     36905,
					     36906,
					     36903,
					     36904,
					     36901,
					     36907,
					     37921},
-- List of names for Lick King herbs
	["lichkingstrings"] 	  = {"Frost Lotus", 
				     "Lichbloom", 
				     "Icethorn", 
				     "Adder\'s Tongue", 
				     "Tiger Lily", 
				     "Goldclover", 
				     "Talandra\'s Rose", 
				     "Deadnettle"},

	["all"]		 	          = { },
	["allstrings"]		 	  = { },
	["allcolors"]			  = { },
	["none"]			  = { }
}

local DEBUG = false
-- store sizes of tables
if (DEBUG) then
      assert( #(items.classic) == #(items.classicstrings),
	   "Mismatched classic table sizes: ID " .. tonumber(#(items.classic)) 
	   .. " and Strings " .. tonumber(#(items.classicstrings)))
   assert( #(items.burningcrusade) == #(items.burningcrusadestrings),
	   "Mismatched Burning Crusade table sizes: ID " .. tonumber(#(items.burningcrusade)) 
	   .. " and Strings " .. tonumber(#(items.burningcrusadestrings)))
   assert( #(items.lichking) == #(items.lichkingstrings),
	   "Mismatched Lich King table sizes: ID " .. tonumber(#(items.lichking)) 
	   .. " and Strings " .. tonumber(#(items.lichkingstrings)))
end

for _,v in pairs (items.classic) do
   tinsert(items.all,v)
end

for _,v in pairs (items.classicstrings) do
   tinsert(items.allstrings, v)
   tinsert(items.allcolors,CLASSIC_COLOR)
end

for k,v in pairs (items.burningcrusade) do 
	tinsert(items.all, v)
end

for _,v in pairs (items.burningcrusadestrings) do 
	tinsert(items.allstrings, v)
        tinsert(items.allcolors,BC_COLOR)
end

for _,v in pairs (items.lichking) do 
	tinsert(items.all, v)
end

for _,v in pairs (items.lichkingstrings) do 
	tinsert(items.allstrings, v)
	tinsert(items.allcolors, LK_COLOR)
end

local defaults = {
   profile = {
      showShort  = true,
      showIcons  = false,
      iconsOnly  = false,
      showZero   = true,
      showBank   = true,
      showAlts   = true,
      showCl     = false, 
      showBC     = true,
      showLK     = true,
      display    = "all",
      updatetime = 1,
      scale      = 1,
   },
   realm = {
      chars = {
	 ['*'] = {
	    data = {
	       ['*'] = { inv = 0, bank = 0, track = false, },
	    }
	 }
      }
   }
}

StaticPopupDialogs["CMFScale"] = {
	text = L["Scale Popup"],
	hasEditBox = 1,
	maxLetters = 3,
	OnShow = function(self)
		local editBox = self.editBox
		editBox:SetText( db.scale )
		editBox:HighlightText()
	end,

	EditBoxOnEnterPressed = function(self)
		local editBox = self:GetParent().editBox
		local input = editBox:GetText()
		scale = tonumber(input)
		if type(scale) == "number" then
			if scale <= 1.2 and scale ~= 0 then
				addon:UpdateScale()
				self:GetParent():Hide()
			else
				self:GetParent():Hide()
				StaticPopup_Show ("CMFScale")
			end
		else 
			self:GetParent():Hide()
			StaticPopup_Show ("CMFScale")
		end
	end,

	EditBoxOnEscapePressed = function(self)
		self:GetParent():Hide()
	end,
	timeout = 0,
	whileDead = 1,
	hideOnEscape = 1
}

StaticPopupDialogs["CMFTimer"] = {
	text = L["Update Popup"],
	hasEditBox = 1,
	maxLetters = 2,
	OnShow = function(self)
		local editBox = self.editBox
		editBox:SetText( db.updatetime )
		editBox:HighlightText()
	end,

	EditBoxOnEnterPressed = function(self)
		local editBox = self:GetParent().editBox
		local input = editBox:GetText()
		updatetime = tonumber(input)
		if type(updatetime) == "number" then
			if updatetime >= 1 and updatetime <= 30 and updatetime ~= 0 then
				addon:UpdateTimer()
				self:GetParent():Hide()
			else
				self:GetParent():Hide()
				StaticPopup_Show ("CMFTimer")
			end
		else 
			self:GetParent():Hide()
			StaticPopup_Show ("CMFTimer")
		end
	end,

	EditBoxOnEscapePressed = function(self)
		self:GetParent():Hide()
	end,
	timeout = 0,
	whileDead = 1,
	hideOnEscape = 1
}

StaticPopupDialogs["CMFPurge"] = {
	text = "",
	button1 = L["Yes"],
	button2 = L["No"],
	OnAccept = function() addon:PurgeData(charToPurge) end,
	timeout = 0,
	whileDead = 1,
	hideOnEscape = 1
}

local function timerpopup()
StaticPopup_Show ("CMFTimer")
end

local function scalepopup()
StaticPopup_Show ("CMFScale")
end

local function charpurge()
StaticPopup_Show ("CMFPurge")
end

local BCMDropDownMenu = CreateFrame("Frame", "BCMDropDownMenu")
BCMDropDownMenu.displayMode = "MENU"
BCMDropDownMenu.info = {}
BCMDropDownMenu.uncheck = function(dropdownbutton)
    _G[dropdownbutton:GetName().."Check"]:Hide()
end

local info = {}
BCMDropDownMenu.initialize = function(self, level)
	if not level then return end
    local info = self.info
    wipe(info)
    if level == 1 then
   	    info.isTitle 	  = 1
   	    info.text 		  = MODNAME
   	    info.notCheckable = 1
   	    UIDropDownMenu_AddButton(info, level)

   	    info.isTitle 	  = 1
   	    info.text 		  = L["Version: "] .. addonversion
   	    UIDropDownMenu_AddButton(info, level)

   	    info.isTitle 	  = 1
   	    info.text 		  = L["Author: "] .. addonauthor
   	    UIDropDownMenu_AddButton(info, level)

   	    info.isTitle 	  = 1
   	    info.text 		  = L["Build Date: "] .. builddate
   	    UIDropDownMenu_AddButton(info, level)

	    info.keepShownOnClick = 1
   	    info.isTitle 	  = nil
   	    info.notCheckable = nil

        info.text 		  = ""
        info.disabled     = 1
        UIDropDownMenu_AddButton(info, level)

        info.disabled     = nil

 	    info.text 		  = L["Include Zero Counts"]
    	info.func   	  = function() db.showZero = not db.showZero addon:Update() end
   		info.checked 	  = function() return db.showZero end
    	UIDropDownMenu_AddButton(info, level)

 	    info.text 		  = L["Include Bank Counts"]
    	info.func   	  = function() db.showBank = not db.showBank addon:Update() end
   		info.checked 	  = function() return db.showBank end
    	UIDropDownMenu_AddButton(info, level)

 	    info.text 		  = L["Include Alt Counts"]
    	info.func   	  = function() db.showAlts = not db.showAlts addon:Update() end
   		info.checked 	  = function() return db.showAlts end
    	UIDropDownMenu_AddButton(info, level)

   	    info.checked      = nil	
        info.text 		  = ""
        info.disabled     = 1
        UIDropDownMenu_AddButton(info, level)

        info.disabled     = nil
		info.notCheckable = 1
   	    info.hasArrow 	  = 1

        info.text 		  = L["Expansion Pack Select"]
   	    info.value 		  = "submenu1"
        info.func 		  = self.uncheck
        UIDropDownMenu_AddButton(info, level)

        info.text 		  = L["Tracking Options"]
   	    info.value 		  = "submenu2"
        UIDropDownMenu_AddButton(info, level)

        info.text 		  = L["Purge"]
   	    info.value 		  = "submenu3"
        UIDropDownMenu_AddButton(info, level)

    	info.value        = nil
		info.hasArrow     = nil

        info.text 		  = L["Tooltip Scale"]
   	    info.func 		  = scalepopup 
        UIDropDownMenu_AddButton(info, level)

        info.text 		  = L["Update Time"]
   	    info.func 		  = timerpopup 
        UIDropDownMenu_AddButton(info, level)

        info.text 		  = ""
        info.disabled     = 1
        UIDropDownMenu_AddButton(info, level)

        info.disabled     = nil

        info.text         = L["Close"]
        info.func         = function() CloseDropDownMenus() end
        UIDropDownMenu_AddButton(info, level)

   	elseif level == 2 then
        if UIDROPDOWNMENU_MENU_VALUE == "submenu1" then
	   info.keepShownOnClick = 1
	   
	   info.text 	 = (BC_COLOR..L["The Burning Crusade"].."|r")
	   info.func    = function() db.showBC = not db.showBC addon:Update() end
	   info.checked = function() return db.showBC end
	   UIDropDownMenu_AddButton(info, level)
	   
	   info.text 	 = (LK_COLOR..L["The Wrath of the Lich King"].."|r")
	   info.func    = function() db.showLK = not db.showLK addon:Update() end
	   info.checked = function() return db.showLK end
	   UIDropDownMenu_AddButton(info, level)

	   info.text    =(CLASSIC_COLOR..L["Classic"].."|r")
	   info.func    = function() db.showCl = not db.showCl addon:Update() end
	   info.checked = function() return db.showCl end
	   UIDropDownMenu_AddButton(info, level)
	end
        if UIDROPDOWNMENU_MENU_VALUE == "submenu2" then
			info.keepShownOnClick = 1

	    	info.text 	 = L["Show Short Text"]
    		info.func    = function() db.showShort = not db.showShort addon:Update() end
   			info.checked = function() return db.showShort end
    		UIDropDownMenu_AddButton(info, level)

	    	info.text 	 = L["Show Icons"]
    		info.func    = function() db.showIcons = not db.showIcons addon:Update() end
   			info.checked = function() return db.showIcons end
    		UIDropDownMenu_AddButton(info, level)

	    	info.text 	 = L["Show Icons Only"]
    		info.func    = function() db.iconsOnly = not db.iconsOnly addon:Update() end
   			info.checked = function() return db.iconsOnly end
    		UIDropDownMenu_AddButton(info, level)

    		for k,v in pairs (items.all) do
				local name = items.allstrings[k]
				local color = items.allcolors[k]
				item  = color..name.."|r" 
		     	info.text 	 = item 
	    		info.func    = function() chardb.data[name].track = not chardb.data[name].track addon:Update() end
	   			info.checked = function() return chardb.data[name].track end
	    		UIDropDownMenu_AddButton(info, level)
			end
		end
        if UIDROPDOWNMENU_MENU_VALUE == "submenu3" then
    		for k,v in pairs (charsToPurge) do 
	    	 	info.text 	 = names[k]
    			info.func    = function() 
					  charToPurge = v StaticPopupDialogs["CMFPurge"].text 
					     = L["PurgePop"]..v..L["PurgePop2"] StaticPopup_Show("CMFPurge") 
				       end
		   	    info.notCheckable = 1
		   	    UIDropDownMenu_AddButton(info, level)
			end
		end
	end
end

local options = nil
local function fullOptions()
	if (not options) then
		options = {
			type = "group",
			name = MODNAME,
			args = {
				general = {
					order	= 5,
					type	= "group",
					name	= L["General Information"],
					args	= {
						header1 = {
							order	= 10,
							type	= "header",
							name	= L["General Information"],
						},
						author = {
							order	= 20,
							type	= "description",
							name	= L["Author: "] .. addonauthor .. "\n",
						},
						version = {
							order	= 25,
							type	= "description",
							name	= L["Version: "] .. addonversion .. "\n",
						},
						builddate = {
							order	= 30,
							type	= "description",
							name	= L["Build Date: "] .. builddate .. "\n",
						},
					},
				},
			},
		}
	end
	for k,v in pairs(modularOptions) do
		options.args[k] = (type(v) == "function") and v() or v
	end
	return options
end

local displayOptions = nil
local function giveDisplay()
	if (not displayOptions) then
			displayOptions = {
				order = 5,
				type = "group",
				name = L["Display Options"],
				args = {
			nulloption = {
				order = 10,
				type  = "header",
				name  = L["Display Options"],
			},
			Zero = {
				type = "toggle",
				order = 15,
				name  = L["Include Zero Counts"],
				get   = function() return db.showZero end,
				set   = function() db.showZero = not db.showZero
						addon:Update()
						end,
			},
			Bank = {
				type = "toggle",
				order = 20,
				name  = L["Include Bank Counts"],
				get   = function() return db.showBank end,
				set   = function() db.showBank = not db.showBank
						addon:Update()
						end,
			},
			Alts = {
				type = "toggle",
				order = 25,
				name  = L["Include Alt Counts"],
				get   = function() return db.showAlts end,
				set   = function() db.showAlts = not db.showAlts
						addon:Update()
						end,
			},
			nulloption1 = {
				order = 45,
				type  = "header",
				name  = L["Expansion Pack Select"],
			},
			classic = {
			   type  = "toggle",
			   order = 49,
			   name  = (CLASSIC_COLOR..L["Classic"].."|r"),
			   get   = function() return db.showCl end,
			   set   = function() db.showCl = not db.showCl
				      addon:Update()
				   end,
			},
			burningcrusade = {
				type  = "toggle",
				order = 50,
				name  = (BC_COLOR..L["The Burning Crusade"].."|r"),
				get   = function() return db.showBC end,
				set   = function() db.showBC = not db.showBC
						addon:Update()
						end,
			},
			lichking = {
				type  = "toggle",
				order = 55,
				name  = (LK_COLOR..L["The Wrath of the Lich King"].."|r"),
				get   = function() return db.showLK end,
				set   = function() db.showLK = not db.showLK
						addon:Update()
						end,
			},		
			nulloption2 = {
				order = 60,
				type  = "header",
				name  = "",
			},
			Scale = {
				order   = 65,
				type	= "range",
				name	= L["Tooltip Scale"],
				min		= .5,
				max		= 2.0,
				step	= .05,
				bigStep = .05,
				get		= function() return db.scale end,
				set		= function( info, v ) 
						  db.scale = v
						  tooltip:SetScale( v )
						  end,
			},
			Time = {
				order   = 70,
				type	= "range",
				name	= L["Update Time"],
				min		= 1,
				max		= 30,
				step	= 1,
				bigStep = 1,
				get		= function() return db.updatetime end,
				set		= function( info, v ) 
						  updatetime = v
						  addon:UpdateTimer()
						  end,
			},
			nulloption3 = {
				order = 75,
				type  = "header",
				name  = L["Purge"],
			},
			Purge = {
				type   = "select",
				order  = 80,
				name   = L["Purge"],
				set    = function(_, name) 
					    charToPurge = name StaticPopupDialogs["CMFPurge"].text 
					       = L["PurgePop"]..name..L["PurgePop2"] StaticPopup_Show("CMFPurge") end,
				values = charsList,
			},
		},
	}
	end
	return displayOptions
end

local trackOptions = nil
local function giveTrack()
	if (not trackOptions) then
			trackOptions = {
				order = 1,
				type = "group",
				name = L["Tracking Options"],
				args = {
			nulloption = {
				order = 5,
				type  = "header",
				name  = L["Tracking Options"],
			},
			Tracker = {
				type  = "toggle",
				order = 10,
				name  = L["Show Short Text"],
				get	  = function() return db.showShort end,
				set   = function() db.showShort = not db.showShort 
						addon:Update()
						end,
			},
			Icons = {
				type = "toggle",
				order = 15,
				name  = L["Show Icons"],
				get   = function() return db.showIcons end,
				set   = function() db.showIcons = not db.showIcons
						addon:Update()
						end,
			},
			IconsOnly = {
				type = "toggle",
				order = 20,
				name  = L["Show Icons Only"],
				get   = function() return db.iconsOnly end,
				set   = function() db.iconsOnly = not db.iconsOnly
						addon:Update()
						end,
			},
			nulloption0 = {
				order = 25,
				type  = "header",
				name  = "",
			},
		},
	}
	local trackerIndex = 30
	for k, v in pairs (items.all) do
		local name = items.allstrings[k] 
		local color = items.allcolors[k]
		local item  = color..name.."|r" 
		trackerIndex = trackerIndex  + 5
		trackOptions.args[name] = {
			type  = "toggle",
			name  = item,
			order = trackerIndex,
			get   = function() return chardb.data[name].track end,
			set   = function() chardb.data[name].track = not chardb.data[name].track
					addon:Update()
					end,
		}
	end
	end
	return trackOptions
end

local function HideTooltip()
   tooltip:SetScript( "OnLeave", nil )
   tooltip:Hide()
   tooltip:Clear()
   LTT:Release(addon.tooltip)
   addon.tooltip = nil
end

-- stringList: string list of items to display
-- color: color in |c then hex format
-- Adds the given list of strings to the tooltip with color
local function DrawTooltipList(stringList, color)
   if DEBUG then 
      print("In DrawTooltipList function", color)
   end

   for _, element in pairs(stringList) do
	 if db.showZero or addon:CharHasElement(element) then
	    local item
	    item  = color..element.."|r"
	    tooltip:AddLine( item, " ", addon:TooltipElements(element) )
	 end -- matches inner if statement
      end -- matches for loop
   end

local function drawTooltip()
 
   if DEBUG then 
      print("drawTooltip called") 
   end

   local colnum = 3
   db.display = db.showCl or db.showBC or db.showLK
  
   if DEBUG then 
      print("db.display : ",db.display) 
   end

   if db.showAlts then
      for _ in pairs(charsdb) do	
		    colnum = colnum + 1
      end
      tooltip:SetColumnLayout(colnum, "LEFT", "CENTER", "CENTER", addon:CharColumnns(layout))	
   else
      tooltip:SetColumnLayout(colnum, "LEFT", "CENTER", "CENTER")
   end

   if db.showAlts and db.display then 
      tooltip:AddLine( " ", " ", addon:TooltipNames() )
   end
   
   if DEBUG then 
      print("db.showCl : ", db.showCl)
      print("db.showBC : ", db.showBC)
      print("db.showLK : ", db.showLK)
   end

   if db.showCl then
      DrawTooltipList(items.classicstrings, CLASSIC_COLOR) 
   end
   if db.showBC then
      DrawTooltipList(items.burningcrusadestrings, BC_COLOR)
   end
   if db.showLK then
      DrawTooltipList(items.lichkingstrings, LK_COLOR)
   end

   if DEBUG then 
      print("Drawing list done.")
   end
   
      linecount = tooltip:GetLineCount() 
   if linecount == 0 then x = 0 else x = 1 end	
   tooltip:AddLine( " " )
   tooltip:AddLine( "" )
   tooltip:SetCell(linecount + ( x + 1 ), 1, L["Left-click for Tracking options panel."], "LEFT", colnum)
   tooltip:AddLine( "" )
   tooltip:SetCell(linecount + ( x + 2 ), 1, L["Shift-Left-click for Display options panel."], "LEFT", colnum)
   tooltip:AddLine( "" )
   tooltip:SetCell(linecount + ( x + 3 ), 1, L["Right-click for Dropdown options menu."], "LEFT", colnum)
end

local bcm = LDB:NewDataObject( MODNAME, {
	type  = "data source",
	text  = " ",
	label = MODNAME,
	icon  = "Interface\\AddOns\\Broker_HerbInventory\\icon",

	OnClick = function( self, button )
		HideTooltip()
		if button == "RightButton" then
			ToggleDropDownMenu(1, nil, BCMDropDownMenu, self, 0, 0)
		elseif
			button == "LeftButton" then
			addon:ShowTracking()
			if IsShiftKeyDown() then			
				addon:ShowDisplay()
			end
		end
	end,

	OnEnter = function ( self )
		tooltip = LTT:Acquire( MODNAME.."TT")
		tooltip:Clear()
		tooltip:SetScale( db.scale )
		tooltip:EnableMouse()
		tooltip:SmartAnchorTo( self )
		drawTooltip()
		tooltip:Show()
	end,

	OnLeave = function ( self )
		if MouseIsOver( tooltip ) then
			tooltip:SetScript( 'OnLeave', HideTooltip )
		else
			HideTooltip()
		end
	end,
} )

local function onTextUpdate()
	local tracktext = ""
	local textcount = 0
	local name, color, icon, item, shortname
	for k, v in pairs(items.all) do
		name = items.allstrings[k]
		icon = "|T"..iconpath..name..":0|t"
		color = items.allcolors[k]
		item  = color..name.."|r"
		if chardb.data[name].track then
			if chardb.data[name].track then
				textcount = textcount + 1
			else
			    textcount = textcount - 1
			end
			if db.showShort then
		        shortname = L["Short_" .. (name)]
				item = color..shortname.."|r"
		    end
			if db.showIcons and not db.iconsOnly then
				item = icon .. " " .. item
			elseif db.showIcons and db.iconsOnly then
				item = icon
			else
				item = item
		    end
			if textcount == 1 then
				tracktext = tracktext .. " " .. (item) .. " " .. Crayon:Colorize(Crayon:GetThresholdHexColor(chardb.data[name].inv, 0, 5, 10), chardb.data[name].inv)
			else
				tracktext = tracktext .. " | " .. (item) .. " " .. Crayon:Colorize(Crayon:GetThresholdHexColor(chardb.data[name].inv, 0, 5, 10), chardb.data[name].inv)
			end
		end
	end	    
	bcm.text = tracktext
end

function addon:OnInitialize()
	self.charName = playerName
	self.db = LibStub("AceDB-3.0"):New("Broker_HerbInventory_DB", defaults, true)
	self.db.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged")
	self.db.RegisterCallback(self, "OnProfileCopied", "OnProfileChanged")
	self.db.RegisterCallback(self, "OnProfileReset", "OnProfileChanged")
	db = self.db.profile
	chardb = self.db.realm.chars[self.charName]
	charsdb = self.db.realm.chars
	if not chardb.class then
		chardb.class = strupper(select(2,UnitClass("player")))
	end
	for name in pairs(charsdb) do
	    charsList[name] = name
	end
end

function addon:OnEnable()
  	self.updateTimer = self:ScheduleRepeatingTimer("CountInv", db.updatetime)
	self:Update()
	self:SetupOptions()
end

function addon:OnDisable()
	self:CancelTimer(self.updateTimer)
end

function addon:SetupOptions()
	ACR:RegisterOptionsTable(MODNAME, fullOptions)
	self.optionsFrame = ACD:AddToBlizOptions(MODNAME, nil, nil, "general")
	self:RegisterModuleOptions("Display", giveDisplay(), L["Display Options"])
	self:RegisterModuleOptions("Tracking", giveTrack(), L["Tracking Options"])
	self:RegisterModuleOptions("Profiles", ADO:GetOptionsTable(self.db), "Profiles")
end

function addon:RegisterModuleOptions(name, optionsTable, displayName)
	modularOptions[name] = optionsTable
	self.optionsFrame[name] = ACD:AddToBlizOptions(MODNAME, displayName, MODNAME, name)
end

function addon:OnProfileChanged(event, database, newProfileKey)
	db = database.profile
	self:Update()
end

function addon:ShowTracking()
	InterfaceOptionsFrame_OpenToCategory( self.optionsFrame["Tracking"] )
end

function addon:ShowDisplay()
	InterfaceOptionsFrame_OpenToCategory( self.optionsFrame["Display"] )
end

function addon:PurgeData(name)
	self.db.realm[name] = nil
	charsdb[name] = nil
	ReloadUI()
end

function addon:UpdateScale()
	if scale ~= nil then
		db.scale = scale
	else 
		scale = db.scale 
	end
end

function addon:UpdateTimer()
	if updatetime ~= nil then
		db.updatetime = updatetime
	else 
		updatetime = db.updatetime
	end
	self:CancelTimer(self.updateTimer)
  	self.updateTimer = self:ScheduleRepeatingTimer("CountInv", db.updatetime)
end

function addon:Update()
	linecount = 0
	x = 0
	onTextUpdate()
end

function addon:TooltipNames()
	local name, alt
	name = "|cff".. classColors[chardb.class] .. self.charName .. "|r"
	names = { name }
	charsToPurge = { self.charName }
 	if db.showAlts then
		for char, _ in pairs(charsdb) do
	    	if char ~= self.charName then
				alt = "|cff".. classColors[charsdb[char].class] .. char .. "|r"
	    		tinsert(names, alt)
	    		tinsert(charsToPurge, char)   	
	    	end
		end
	end
	return unpack(names)
end

function addon:CharColumnns(layout)
	justification = {}
		for _ in pairs(charsdb) do	
	    	tinsert(justification, "CENTER")
		end
	return unpack(justification)
end

function addon:CharHasElement(element)
	if chardb.data[element].inv > 0 or (db.showBank and chardb.data[element].bank > 0) then
		return true
	end
    if db.showAlts then
		for char, _ in pairs(charsdb) do
			if charsdb[char].data[element].inv > 0 or (db.showBank and charsdb[char].data[element].bank > 0) then
				return true
			end
		end
	end
	return false
end

function addon:TooltipElements(element)
	local elements = { self:CountString(element) }
	if db.showAlts then
		for char, _ in pairs(charsdb) do
		   if char ~= self.charName then
		      tinsert(elements, self:CountString(element, char))	    	
		   end
		end
	end 
	return unpack(elements)
end

function addon:CountString(element, char)
	return self:InvCountString(element, char) .. self:BankCountString(element, char)
end

function addon:InvCountString(element, char)
	local tempChar = chardb	
	if char then
		tempChar = charsdb[char]
	end	
	return Crayon:Colorize(Crayon:GetThresholdHexColor(tempChar.data[element].inv, 0, 5, 10), tempChar.data[element].inv)
end 

function addon:BankCountString(element, char)
	local tempChar = chardb
	if char then
		tempChar = charsdb[char]
	end	
	if db.showBank then
		return " (" .. 
	      Crayon:Colorize(Crayon:GetThresholdHexColor(tempChar.data[element].bank, 0, 5, 10), tempChar.data[element].bank) .. ")"
	else
		return " "
	end
end

function addon:CountInv()	
	local data = chardb.data
	for k,v in pairs (items.all) do 
		local item = items.allstrings[k]
		local inv = GetItemCount ( v )
		local bank = GetItemCount ( v, true )
		bank = bank - inv
		data[item].inv = inv
		data[item].bank = bank
	end
end